/**
 * Set filter for ag-grid
 * @constructor
 */

var _slice = Array.prototype.slice;
var template_item_inner = '' +
    '<label> \
      <input type="checkbox" class="ag-filter-checkbox" filter-checkbox="true"/> \
      <span class="ag-filter-value"></span> \
    </label>';

var template = '' +
    '<div> \
        <div class="ag-filter-list-viewport"> \
            <div class="ag-filter-list-container"> \
            </div> \
        </div> \
     </div>';

function ShuiminSetFilter() {
    /* The col def this filter is for */
    this.colDef = null;

    /* The internal row Model inside ag-Grid. This should
     be treated as read only. If the filter needs to 
     know which rows are
     a) in the table
     b) currently visible
     c) what groups
     d) what order
     all of this can be read from the rowModel. */
    this.rowModel = null;


    /* A function callback, to be called, when the filter changes,
     to inform the grid to filter the data.
     The grid will respond bt filtering the data.*/
    this.filterChangedCallback = null;

    /* A function callback, to be OPTIONALLY called,
     when the filter changes, but before 'Apply' is pressed.
     The grid will responed by filtering the data. */

    this.filterModifiedCallback = null;

    /* A function callback,
     call with a node to be given the value for that filters column for that node.
     The callback takes care of selecting the right colDef and decideing whether to use valueGetter or field etc.
     */

    this.valueGetter = null;

    /* A function callback, call with a node to be told
     whether the node passes all filters 
     except the current filter. 
     This is useful if you want to only present
     to the user values that this 
     filter can filter given the status of
     the other filters. The set filter
     uses this to remove from the list, 
     items that are no longer avaliable
     due to the state if other filters
     (like Excel type filtering).
     */

    this.doesRowPassOtherFilter = null;

    /* The filter parameters, as provided in the column definition */
    this.filterParams = null;

    /* The context for this grid */
    this.context = null;

    /* The ng-scope */
    this.$scope = null;

}

// mandatory methods
ShuiminSetFilter.prototype.init = function (p) {
    this.colDef = p.colDef;
    this.rowModel = p.rowModel;
    this.filterChangedCallback = p.filterChangedCallback;
    this.filterModifiedCallback = p.filterModifiedCallback;
    this.valueGetter = p.valueGetter;
    this.doesRowPassOtherFilter = p.doesRowPassOtherFilter;
    this.filterParams = p.filterParams;
    this.context = p.context;
    this.$scope = p.$scope;

    this.gui = document.createElement('div');

    // console.log(p.filterParams);

    //{value, view }
    this.all_options = _slice.call(p.filterParams, 0) || [];

    //{value, view }
    this.options = _slice.call(p.filterParams, 0) || [];

}

function updateModel(filter, model) {
    filter.options = model.options;
    setupEvent(filter);
}

function setupTemplate() {
    return template
        .replace('[SELECT ALL]', '全部')
        .replace('[SEARCH...]', '条件...')
        .replace('[APPLY FILTER]', '查询');
}

function setupEvent(filter) {
    filter.gui.innerHTML = setupTemplate();

    //var $option_filter =
    // filter.$option_filter = filter.gui.querySelector('#option_filter');

    var select_all = filter.gui.querySelector('#selectAll');

    var container = filter.gui.querySelector('.ag-filter-list-container');

    /*
     select_all.addEventListener('click', function(){
     var all_checkbox = container.querySelectorAll('input[type="checkbox"]');
     console.log('all-checkboxies', all_checkbox);
     _slice.call(all_checkbox,0).forEach(function(node){
     console.log(arguments);
     node.dispatchEvent('click');
     });
     });
     */
    //bindings
    // $option_filter.addEventListener('changed', listener);
    // $option_filter.addEventListener('paste', listener);
    // $option_filter.addEventListener('input', listener);
    // $option_filter.addEventListener('keydown', listener);
    // $option_filter.addEventListener('keyup', listener);

    function create_filter_item(item) {
        // console.log('creating item', item);
        var ret = document.createElement('div');
        ret.setAttribute('class', 'ag-filer-item');
        ret.innerHTML = template_item_inner;
        var $checkbox = ret.querySelector('input[type="checkbox"]');
        $checkbox.checked = item.checked;

        $checkbox.addEventListener('click', function (e) {
            //trigger callback
            item.checked = !item.checked;
            filter.filterChangedCallback();
        });
        var $span = ret.querySelector('.ag-filter-value');
        $span.textContent = item.view;
        return ret;
    }

    function render_filter_items() {
        //clear
        if (container.hasChildNodes()) {
            Array.prototype.slice.call(container.childNodes, 0).forEach(function (n) {
                container.removeChild(n);
            });
        }
        //render as options
        filter.options.forEach(function (option) {
            container.appendChild(create_filter_item(option));
        });

    }

    /**
     function listener(event) {
    filter.option_filter_text = event.target.value;
    //update options
    filter.options = filter.all_options
    .filter(function(option){
      return option.value && 
        option.value.indexOf(filter.option_filter_text) != -1
    });

    render_filter_items();
  }*/
    render_filter_items();
}

ShuiminSetFilter.prototype.getGui = function () {
    setupEvent(this);
    return this.gui;
}

ShuiminSetFilter.prototype.selectedFilterItems = function () {
    return this.options.filter(function (o) {
        return o.checked
    })
}

/**
 The grid will ask each active filter, in turn,
 whether each row in the grid passes.
 If any filter fails, then the row will be excluded from the final set.
 The method is provided the
 value (the value to be checked),
 the row node,
 the row data
 and the filter model (for the filter, as provided by the 'get model' below - for now, the model can be ignored).
 */
ShuiminSetFilter.prototype.isFilterActive = function () {
    return this.options.length !== this.all_options.length ||
        this.selectedFilterItems().length < this.all_options.length;
}

ShuiminSetFilter.prototype.doesFilterPass = function (node) {
    var selected_items = this.selectedFilterItems();
    var selected_values = selected_items.map(function (x) {
        return x.value
    });
    var value = this.valueGetter(node);

    //ignore undefiend value
    if (value) return true;

    return -1 != selected_values.indexOf(value);

}

ShuiminSetFilter.prototype.getApi = function () {
    var that = this;
    return {
        getModel: function () {
            return {
                type       : 'set',
                options    : that.options,
                all_options: that.all_options,
                values     : that.options.filter(function (o) {
                    return o.checked
                })
                    .map(function (o) {
                        return o.value
                    })
            }
        },
        setModel: function (model) {
            updateModel(that, model)
        }
    }
}

//optinal methods


ShuiminSetFilter.prototype.afterGuiAttached = function () {
}
ShuiminSetFilter.prototype.onNewRowsLoaded = function () {
}
ShuiminSetFilter.prototype.onAnyFilterLoaded = function () {
}
ShuiminSetFilter.prototype.destory = function () {
}

// console.log('ready to export', ShuiminSetFilter);
module.exports = ShuiminSetFilter;
